@using Umbraco.Cms.Core
@using Umbraco.Cms.Core.Models.PublishedContent
@using Umbraco.Cms.Core.PublishedCache
@using Umbraco.Cms.Core.Routing
@using Umbraco.Cms.Core.Services.Navigation
@using Umbraco.Extensions
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@inject IPublishedValueFallback PublishedValueFallback
@inject IPublishedUrlProvider PublishedUrlProvider
@inject IDocumentNavigationQueryService DocumentNavigationQueryService
@inject IPublishedContentStatusFilteringService PublishedContentStatusFilteringService
@*
    This snippet creates links for every single page (no matter how deep) below
    the page currently being viewed by the website visitor, displayed as nested unordered HTML lists.
*@

@{ var selection = Model?.Content.Children(DocumentNavigationQueryService, PublishedContentStatusFilteringService).Where(x => x.IsVisible(PublishedValueFallback)).ToArray(); }

@* Ensure that the Current Page has children *@
@if (selection?.Length > 0)
{
    @* Get the first page in the children, where the property umbracoNaviHide is not True *@
    var naviLevel = selection[0].Level;

    @* Add in level for a CSS hook *@
    <ul class="level-@(naviLevel)">
        @* Loop through the selection *@
        @foreach (var item in selection)
        {
            <li>
                <a href="@item.Url(PublishedUrlProvider)">@item.Name</a>

                @* if this child page has any children, where the property umbracoNaviHide is not True *@
                @{
                    var children = item
                        .Children(DocumentNavigationQueryService, PublishedContentStatusFilteringService)
                        .Where(x => x.IsVisible(PublishedValueFallback))
                        .ToArray();

                    if (children.Length > 0)
                    {
                        @* Call a local method to display the children *@
                        ChildPages(children);
                    }
                }
            </li>
        }
    </ul>
}

@{
    void ChildPages(IPublishedContent[] selection)
    {
        //Ensure that we have a collection of pages
        if (selection.Length > 0)
        {
            // Get the first page in pages and get the level
            var naviLevel = selection[0].Level;

            // Add in level for a CSS hook
            <ul class="level-@(naviLevel)">
                @foreach (var item in selection)
                {
                    <li>
                        <a href="@item.Url(PublishedUrlProvider)">@item.Name</a>

                        @* if the page has any children, where the property umbracoNaviHide is not True *@
                        @{
                            var children = item
                                .Children(DocumentNavigationQueryService, PublishedContentStatusFilteringService)
                                .Where(x => x.IsVisible(PublishedValueFallback))
                                .ToArray();

                            if (children.Length > 0)
                            {
                                @* Recurse and call the ChildPages method to display the children *@
                                ChildPages(children);
                            }
                        }
                    </li>
                }
            </ul>
        }
    }
}
